package top.yxqz.spring.aop.xml;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
 * @author: 余小小
 * @date: 2023/4/12
 * @description：切面类 封装通知方法的类。
 * @Aspect: 切面，表示当前类是一个切面类
 * 通知的种类
 * 1. 前置通知：在被代理的目标方法前执行，
 * 2. 返回通知：在被代理的目标方法成功结束后执行（寿终正寝）
 * 3. 异常通知：在被代理的目标方法异常结束后执行（死于非命）
 * 4. 后置通知：在被代理的目标方法最终结束后执行（盖棺定论）
 * 5. 环绕通知：使用try...catch...finally结构围绕整个被代理的目标方法，包括上面四种通知对应的所 有位置
 */
public class LoggerAspectXml {


    /**
     * 自定义切入点
     */
    public void myPointCut() {
    }

    /**
     * 前置通知，在目标对象方法执行之前执行
     * execution语法（修饰符 返回值 方法的全类名路径（参数类型...））
     * 通配符的写法 execution（* 类的全类名路径.*（..）)
     */
    public void beforeAdviceMethod() {
        System.out.println("1.前置通知————————————beforeAdviceMethod");
    }

    /**
     * 后置通知：在目标方法执行之后执行
     */
    public void afterAdviceMethod() {
        System.out.println("2.后置通知————————————afterAdviceMethod");
    }

    /**
     * 返回通知
     */
    public void afterAdviceReturningMethod(Object myResult) {
        System.out.println("3.返回通知————————————afterAdviceReturningMethod");
        System.out.println("返回通知里面的值：" + myResult);
    }

    /**
     * 异常通知，目标方法，出现异常，就会触发
     * 后置通知也会触发
     */
    public void afterThrowingAdviceMethod() {
        System.out.println("4.异常通知————————————afterThrowingAdviceMethod");
    }

    /**
     * ProceedingJoinPoint 继续连接点
     */
    public Object aroundAdviceMethod(ProceedingJoinPoint joinPoint) {
        System.out.println("5.环绕通知————————————aroundAdviceMethod");

        Object myResult = null;

        try {
            System.out.println("环绕通知————前置通知");
            myResult = joinPoint.proceed();
        } catch (Throwable e) {
            System.out.println("环绕通知————异常通知");
            throw new RuntimeException(e);
        } finally {
            System.out.println("环绕通知————后置通知");
        }

        return myResult;


    }
}
